<?php

// +----------------------------------------------------------------------
// | 微信支付回调处理相关的业务
// +----------------------------------------------------------------------
// | @author fancsen
// +----------------------------------------------------------------------

namespace app\api\service;

use app\common\lib\exception\ApiException;
use app\common\lib\enum\OrderStatusEnum;
use app\api\service\Order as OrderService;
use app\api\model\Order as OrderModel;
use app\api\model\Product as ProductModel;
use think\Loader;
use think\Log;

Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');

class WxNotify extends \WxPayNotify
{
    /**
	 * 
	 * 回调方法入口，子类重写方法
	 * @param array $data 回调解释出的参数
	 * @param string $msg 如果回调处理失败，可以将错误信息输出到该方法
	 * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
	 */
	public function NotifyProcess($data, &$msg)
	{
		//TODO 用户基础该类之后需要重写该方法，成功的时候返回true，失败返回false
		if ($data['result_code'] == 'SUCCESS'){
            //如果支付成功
            $orderNo = $data['out_trade_no'];//去的订单号
            Db::startTrans();
            try{
                //获取订单信息,同时锁住该订单
                $order = OrderModel::where('order_no','=',$orderNo)->lock(true)->find();
                if($order->status == OrderStatusEnum::UNPAID){
                    //检查库存
                    $orderService = new OrderService();
                    $status = $orderService->checkOrderStock($order->id);
                    if($status['pass']){
                        //更新订单信息
                        $this->updateOrderStatus($order->id,true);
                        $this->reduceStock($status);
                    }else {
                        //库存不足
                        $this->updateOrderStatus($order->id,false);
                    }
                    Db::commit(); 
                    return true;
                }
            }catch(\Exception $e){
                Db::rollback();
                //记录错误日志
                Log::init([
                    'type' => 'File',
                    'path' => LOG_PATH,
                    'level' => ['error']
                ]);
                Log::error($ex);
                return false;
            }
        }else {
            return true;
        }
    }
    

    /**
     * 更新订单状态
     * @param int $orderId 订单id
     * @param string $success 状态
     */
    private function updateOrderStatus($orderId,$success)
    {
        $status = $success ? (OrderStatusEnum::PAID) :  (OrderStatusEnum::PAID_BUT_OUT_OF);

        OrderModel::where('id','=',$orderId)->update(['status'=>$status]);
    }

    /**
     * 减少库存
     * @param array 
     */
    private function reduceStock($status)
    {
        foreach ($status['pStatusArray'] as $key => $value) {
            ProductModel::where('id',$value['id'])->setDec('stock',$value['count']);
        }
    }
}